home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Leser 15 / Amiga Plus Leser CD 15.iso / Tools / Development / MosaicSRC / libwww2 / Unused / HTFwrite.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-03-13  |  12.9 KB  |  489 lines

  1. /*        FILE WRITER                HTFWrite.h
  2. **        ===========
  3. **
  4. **    This version of the stream object just writes to a C file.
  5. **    The file is assumed open and left open.
  6. **
  7. **    Bugs:
  8. **        strings written must be less than buffer size.
  9. */
  10.  
  11. #include "HTFWriter.h"
  12.  
  13. #include "HTFormat.h"
  14. #include "HTAlert.h"
  15. #include "HTFile.h"
  16. #include "HText.h"
  17. #include "tcp.h"
  18. #include "HTCompressed.h"
  19. #ifdef _AMIGA
  20.  #include <string.h>
  21. #endif
  22.  
  23. /*        Stream Object
  24. **        ------------
  25. */
  26.  
  27. struct _HTStream {
  28.     CONST HTStreamClass *    isa;
  29.     
  30.     FILE *            fp;
  31.         char * fnam;
  32.     char *             end_command;
  33.         int compressed;
  34.         int interrupted;
  35.         int write_error;
  36. };
  37.  
  38. /* #define TRACE 1 */
  39.  
  40. /* MOSAIC: We now pick up some external variables, handled
  41.    in src/mo-www.c: */
  42. extern int force_dump_to_file;
  43. extern char *force_dump_filename;
  44. /* If force_dump_to_file is high, we know we want to dump the
  45.    data into a file already named by force_dump_filename and not
  46.    do anything else. */
  47.  
  48. /* If this is high, then we just want to dump the thing to a file;
  49.    the file is named by force_dump_filename. */
  50. extern int binary_transfer;
  51.  
  52. /*_________________________________________________________________________
  53. **
  54. **            A C T I O N     R O U T I N E S
  55. */
  56.  
  57. /*    Character handling
  58. **    ------------------
  59. */
  60.  
  61. PRIVATE void HTFWriter_put_character ARGS2(HTStream *, me, char, c)
  62. {
  63.   int rv;
  64.  
  65.   if (me->write_error)
  66.     return;
  67.  
  68.   /* Make sure argument to putc is in range 0-255, to avoid weirdness
  69.      with rv == -1 == EOF when it's not supposed to. */
  70.   rv = putc ((int)(unsigned char)c, me->fp);
  71.  
  72.   if (rv == EOF)
  73.     {
  74.       HTProgress ("Error writing to temporary file.");
  75.       me->write_error = 1;
  76.     }
  77. }
  78.  
  79.  
  80. /*    String handling
  81. **    ---------------
  82. **
  83. **    Strings must be smaller than this buffer size.
  84. */
  85. PRIVATE void HTFWriter_put_string ARGS2(HTStream *, me, CONST char*, s)
  86. {
  87.   int rv;
  88.  
  89.   if (me->write_error)
  90.     return;
  91.  
  92.   rv = fputs(s, me->fp);
  93.   if (rv == EOF)
  94.     {
  95.       HTProgress ("Error writing to temporary file.");
  96.       me->write_error = 1;
  97.     }
  98. }
  99.  
  100.  
  101. /*    Buffer write.  Buffers can (and should!) be big.
  102. **    ------------
  103. */
  104. PRIVATE void HTFWriter_write ARGS3(HTStream *, me, CONST char*, s, int, l)
  105. {
  106.   int rv;
  107.  
  108.   if (me->write_error)
  109.     return;
  110.  
  111.   rv = fwrite(s, 1, l, me->fp); 
  112.   if (rv != l)
  113.     {
  114.       HTProgress ("Error writing to temporary file.");
  115.       me->write_error = 1;
  116.     }
  117. }
  118.  
  119.  
  120. /*    Free an HTML object
  121. **    -------------------
  122. **
  123. **    Note that the SGML parsing context is freed, but the created
  124. **    object is not,
  125. **    as it takes on an existence of its own unless explicitly freed.
  126. */
  127. PRIVATE void HTFWriter_free ARGS1(HTStream *, me)
  128. {
  129.   HText *text;
  130.  
  131.   /* I dunno if this is necessary... */
  132.   if (me->interrupted)
  133.     {
  134.       free (me->fnam);
  135.       free (me);
  136.       return;
  137.     }
  138.  
  139.   if (me->write_error)
  140.     {
  141.       char *cmd = (char *)malloc ((strlen (me->fnam) + 32));
  142. #ifdef _AMIGA      
  143.       sprintf (cmd, "run >NIL: <NIL: delete %s", me->fnam);
  144. #else
  145.       sprintf (cmd, "/bin/rm -f %s &", me->fnam);
  146. #endif      
  147.       system (cmd);
  148.       free (cmd);
  149.  
  150.       HTProgress ("Insufficient temporary disk space; could not transfer data.");
  151.  
  152.       free (me->fnam);
  153.       free (me);
  154.       return;
  155.     }
  156.  
  157.   fflush (me->fp);
  158.   fclose (me->fp);
  159.  
  160.   /* We do want to be able to handle compressed inlined images,
  161.      but we don't want transparent uncompression to take place
  162.      in binary transfer mode. */
  163.   if (!binary_transfer && me->compressed != COMPRESSED_NOT)
  164.     {
  165.       if (TRACE)
  166.         fprintf (stderr, "[HTFWriter] Hi there; compressed is %d, fnam is '%s'\n",
  167.                  me->compressed, me->fnam);
  168.       HTCompressedFileToFile (me->fnam, me->compressed);
  169.     }
  170.  
  171.   if (force_dump_to_file)
  172.     {
  173.       if (!binary_transfer)
  174.         goto done;
  175.     }
  176.  
  177.   /* Now, me->end_command can either be something starting with
  178.      "<mosaic-internal-reference" or it can be a real command.
  179.      Deal with appropriately. */
  180.   if (me->end_command)
  181.     {
  182.       /* Check for forced dump condition.  The left paren comes
  183.          from the construction of me->end_command as a compound shell
  184.          command below. */
  185.       if (strstr (me->end_command, "mosaic-internal-dump"))
  186.         {
  187.           rename_binary_file (me->fnam);
  188.         }
  189.       else if (!strstr (me->end_command, "mosaic-internal-reference"))
  190.         {
  191.           HTProgress("Spawning external viewer.");
  192. #ifdef _AMIGA
  193.       { /*MJW 17 Oct 1993  -- can't put multiple commands on a line,
  194.           so made temporary script instead - updated Nov 7 1993 removed free endcommand*/
  195.             static char AMcommandprefix[]="c:RUN >NIL: <NIL: c:EXECUTE ";
  196.         char *AMcommand=(char *)malloc(strlen(AMcommandprefix)+16+L_tmpnam);
  197.             char *AMcomfile=AMcommand+strlen(AMcommandprefix);
  198.         FILE *AMtmpfile;
  199.             sprintf(AMcommand,AMcommandprefix);
  200.             tmpnam (AMcomfile);
  201.         if (TRACE) fprintf(stderr,"Amiga command string is %s (on %s)\n",
  202.             AMcommand,AMcomfile );
  203.         if ((FILE *)NULL ==(AMtmpfile = fopen(AMcomfile,"w"))){
  204.           HTAlert("Can't open script temporary file!");
  205.           free(AMcommand); 
  206.         } else {
  207.           /* break the command apart at semicolons */
  208.               static char AMdelprefix[]="c:delete >NIL: <NIL: ";
  209.               char *semi;
  210.               char *AMdelcommand=
  211.         (char *)malloc(strlen(AMdelprefix)+16+L_tmpnam);
  212.           sprintf(AMdelcommand,"%s %s",AMdelprefix,AMcomfile);
  213.               for (semi=me->end_command; *semi; semi++) 
  214.         if (*semi == ';') *semi='\n';
  215.               /* Then stick it in a command file */
  216.               fprintf(AMtmpfile,".bra {\n");
  217.           fprintf(AMtmpfile,".ket }\n\n");
  218.           fprintf(AMtmpfile,"%s\n\n",me->end_command);
  219.               fclose(AMtmpfile);
  220.               system(AMcommand);
  221.           free(AMcommand); 
  222.               system(AMdelcommand);
  223.           free(AMdelcommand);
  224.         }
  225.       }
  226. #else         /* Not an amiga */
  227.           system (me->end_command);
  228. #endif        /* ! _AMIGA */
  229.         }
  230.       else
  231.         {
  232.           /* Internal reference, aka HDF file.  Just close output file. */
  233.         }
  234.     }
  235.   else
  236.     {
  237.       /* No me->end_command; just close the file. */
  238.     }
  239.  
  240.   /* Construct dummy HText thingie so Mosaic knows
  241.      not to try to access this "document". */
  242.   text = HText_new ();
  243.   HText_beginAppend (text);
  244.   /* If it's a real internal reference, tell Mosaic. */
  245.   if (me->end_command)
  246.     {
  247.       if (strstr (me->end_command, "mosaic-internal-reference"))
  248.         {
  249.           HText_appendText (text, me->end_command);
  250.         }
  251.       else
  252.         {
  253.           HText_appendText (text, "<mosaic-access-override>\n");
  254.         }
  255.       free (me->end_command);
  256.     }
  257.   else
  258.     {
  259.       /* No me->end_command; just override the access. */
  260.       HText_appendText (text, "<mosaic-access-override>\n");
  261.     }
  262.   HText_endAppend (text);
  263.  
  264.  done:
  265.   if (binary_transfer)
  266.     rename_binary_file (me->fnam);
  267.  
  268.  really_done:
  269.   free (me->fnam);
  270.   free (me);
  271.  
  272.   return;
  273. }
  274.  
  275. /*    End writing
  276. */
  277.  
  278. PRIVATE void HTFWriter_end_document ARGS1(HTStream *, me)
  279. {
  280.   if (me->interrupted || me->write_error)
  281.     return;
  282.  
  283.   fflush(me->fp);
  284. }
  285.  
  286. PRIVATE void HTFWriter_handle_interrupt ARGS1(HTStream *, me)
  287. {
  288.   char *cmd;
  289.  
  290.   if (me->write_error)
  291.     goto outtahere;
  292.  
  293.   /* Close the file, then kill it. */
  294.   fclose (me->fp);
  295.  
  296.   cmd = (char *)malloc ((strlen (me->fnam) + 32) * sizeof (char));
  297. #ifdef _AMIGA      
  298.       sprintf (cmd, "run >NIL: <NIL: delete %s", me->fnam);
  299. #else
  300.       sprintf (cmd, "/bin/rm -f %s &", me->fnam);
  301. #endif      
  302.   system (cmd);
  303.   free (cmd);
  304.  
  305.   if (TRACE)
  306.     fprintf (stderr, "*** HTFWriter interrupted; killed '%s'\n", me->fnam);
  307.   
  308.  outtahere:
  309.   me->interrupted = 1;
  310.  
  311.   return;
  312. }
  313.  
  314.  
  315. /*    Structured Object Class
  316. **    -----------------------
  317. */
  318. PRIVATE CONST HTStreamClass HTFWriter = /* As opposed to print etc */
  319. {        
  320.     "FileWriter",
  321.     HTFWriter_free,
  322.     HTFWriter_end_document,
  323.     HTFWriter_put_character,     HTFWriter_put_string,
  324.     HTFWriter_write,
  325.         HTFWriter_handle_interrupt
  326. }; 
  327.  
  328.  
  329. /*    Take action using a system command
  330. **    ----------------------------------
  331. **
  332. **    Creates temporary file, writes to it, executes system command
  333. **    on end-document.  The suffix of the temp file can be given
  334. **    in case the application is fussy, or so that a generic opener can
  335. **    be used.
  336. **
  337. **      WARNING: If force_dump_to_file is high, pres may be NULL
  338. **      (as we may get called directly from HTStreamStack).
  339. */
  340. PUBLIC HTStream* HTSaveAndExecute ARGS5(
  341.     HTPresentation *,    pres,
  342.     HTParentAnchor *,    anchor,    /* Not used */
  343.     HTStream *,        sink,
  344.         HTFormat,               format_in,
  345.         int,                    compressed)    /* Not used */
  346. {
  347.   char *command;
  348.   CONST char * suffix;
  349.   
  350.   HTStream* me;
  351.  
  352.   me = (HTStream*)malloc(sizeof(*me));
  353.   me->isa = &HTFWriter;  
  354.   me->interrupted = 0;
  355.   me->write_error = 0;
  356.   me->fnam = NULL;
  357.   me->end_command = NULL;
  358.   me->compressed = compressed;
  359.  
  360.   if (TRACE)
  361.     fprintf (stderr, "[HTSaveAndExecute] me->compressed is '%d'\n",
  362.              me->compressed);
  363.   
  364.   /* Save the file under a suitably suffixed name */
  365.   
  366.   if (!force_dump_to_file)
  367.     {
  368.       extern char *mo_tmpnam (void);
  369.  
  370.       suffix = HTFileSuffix(pres->rep);
  371.       
  372.       me->fnam = mo_tmpnam();
  373.       if (suffix) 
  374.         {
  375.           char *freeme = me->fnam;
  376.          
  377.           me->fnam = (char *)malloc (strlen (me->fnam) + strlen (suffix) + 8);
  378.           strcpy(me->fnam, freeme);
  379.           strcat(me->fnam, suffix);
  380.           free (freeme);
  381.         }
  382.     }
  383.   else
  384.     {
  385.       me->fnam = strdup (force_dump_filename);
  386.     }
  387.  
  388.   me->fp = fopen (me->fnam, "w");
  389.   if (!me->fp) 
  390.     {
  391.       HTProgress("Can't open temporary file -- serious problem.");
  392.       me->write_error = 1;
  393.       return me;
  394.     }
  395.  
  396.   /* If force_dump_to_file is high, we're done here. */
  397.   if (!force_dump_to_file)
  398.     {
  399.       if (!strstr (pres->command, "mosaic-internal-reference"))
  400.         {
  401.           /* If there's a "%s" in the command, or if the command
  402.              is magic... */
  403.           if (TRACE)
  404.             fprintf (stderr, "HTFWriter: pres->command is '%s'\n",
  405.                      pres->command);
  406.           if (strstr (pres->command, "%s") ||
  407.               strstr (pres->command, "mosaic-internal"))
  408.             {
  409.               /* Make command to process file */
  410.               command = (char *)malloc 
  411.                 ((strlen (pres->command) + 10 + 3*strlen(me->fnam)) * 
  412.                  sizeof (char));
  413.               
  414.               /* Cute.  pres->command will be something like "xv %s"; me->fnam
  415.                  gets filled in as many times as appropriate.  */
  416.               sprintf (command, pres->command, me->fnam, me->fnam, me->fnam);
  417. #ifdef _AMIGA 
  418.            { /* For the amiga only, if @ appears in the string, 
  419.                 terminate the string there, and append the screen name
  420.             to the command, so the program will run on 
  421.             the screen amosaic is running on */
  422.          /* This hack may be obsolete! as of Mosaic 2.0 */
  423.          char  *scrptr = (char *)strchr(command,'@');
  424.          extern char *gui_whichscreen(void);
  425.          if (scrptr != NULL) {
  426.            *scrptr=(char)0;
  427.            scrptr = gui_whichscreen();    
  428.            me->end_command =
  429.          (char *)malloc((strlen (command)+32+strlen(me->fnam)+strlen(scrptr))
  430.                     * sizeof (char));
  431.            sprintf (me->end_command, "%s PUBSCREEN=\"%s\"; c:delete %s ",
  432.                 command, scrptr, me->fnam);
  433.          } else {
  434.            me->end_command =
  435.          (char *)malloc ((strlen (command) + 32 + strlen(me->fnam))
  436.                  * sizeof (char));
  437.            sprintf (me->end_command, "%s ; c:delete %s ",
  438.                 command, me->fnam);
  439.          }
  440.        }
  441.        
  442. #else /* NOT an AMIGA */
  443.               
  444.               me->end_command = (char *)malloc 
  445.                 ((strlen (command) + 32 + strlen(me->fnam)) * sizeof (char));
  446.               sprintf (me->end_command, "(%s ; /bin/rm -f %s) &",
  447.                        command, me->fnam);
  448. #endif 
  449.               free (command);
  450.             }
  451.           else
  452.             {
  453.               /* Make command to process file -- but we have to cat
  454.                  to the viewer's stdin. */
  455.             #ifdef _AMIGA 
  456.           { 
  457.         fprintf(stderr," Please send email to witbrock@cs.cmu.edu\n"
  458.             "telling him that you passed through the unsupported\n"
  459.             "pipe code and which URL it happened on. "
  460.             " say '((cat %s | %s); /bin/rm -f %s) &'"
  461.             "Also say:\n"
  462.             "\t file %s:%s line %d compiled %s %s\n",
  463.             me->fnam, pres->command, me->fnam,
  464.             __FILE__,__FUNC__,__LINE__,__DATE__,__TIME__);
  465.         fflush(stderr);
  466.           }
  467.           
  468.             #else /* NOT an AMIGA */
  469.               me->end_command = (char *)malloc 
  470.                 ((strlen (pres->command) + 64 + (2 * strlen(me->fnam))) * 
  471.                  sizeof (char));
  472.               sprintf (me->end_command, "((cat %s | %s); /bin/rm -f %s) &",
  473.                        me->fnam, pres->command, me->fnam);
  474.             #endif
  475.             }
  476.         }
  477.       else
  478.         {
  479.           /* Overload me->end_command to be what we should write out as text
  480.              to communicate back to client code. */
  481.           me->end_command = (char *)malloc
  482.             (strlen ("mosaic-internal-reference") + strlen (me->fnam) + 32);
  483.           sprintf (me->end_command, "<%s \"%s\">\n", "mosaic-internal-reference", me->fnam);
  484.         }
  485.     }
  486.   
  487.   return me;
  488. }
  489.